#include "LightInputDriver.h"


LightInputDriver::LightInputDriver (float* pXSpace, float* pYSpace,
                                    Ptr< queue< Request > > pReqQueue)
{
  _pXSpace = pXSpace;
  _pYSpace = pYSpace;
  _pRequestQueue = pReqQueue;

  _pDetector = new LightPosDetector ();
  //_pDetector = new MouseInput ();
  _pCoordTransfer = new PlaneProjectTransfer ();

  if (_pXSpace == NULL)
    return;

  if (!_read_file ())
    throw ("LightInputDriver Init Error");
}




void LightInputDriver::run ()
{
  if (_pXSpace == NULL)
    throw ("Config Mode cannot run.");
  Array< float > cameraPointCoord(2);
  Array< float > projectPointCoord(2);

  while (true)
  {
    projectPointCoord[X] = -1.0f;
    projectPointCoord[Y] = -1.0f;
    if (_pDetector->get_point_input (cameraPointCoord))
      _pCoordTransfer->camera_to_projector (cameraPointCoord, projectPointCoord);
    (*_pXSpace) = projectPointCoord[X];
    (*_pYSpace) = projectPointCoord[Y];
    Sleep (20);
  }
}



bool LightInputDriver::_read_file ()
{
  FileStreamIn input (HOMOGRAPHY_DATA_FILE);
  if (!input)
    return false;
  if (!input.check_file_type (DATA_FILE_TYPE))
  {
    input.close ();
    return false;
  }

  MyMatrix< float > data (2, 5);

  for (int r = 0; r < 2; ++r)
  {
    for (int c = 0; c < 5; ++c)
      input.bin_read< float > (&data[r][c]);
  }

  _pCoordTransfer->set_transfer_data (data);

  input.close ();
  return true;
}



bool LightInputDriver::write_file ()
{
  FileStreamOut output (HOMOGRAPHY_DATA_FILE);
  if (!output)
    return false;

  output.write (DATA_FILE_TYPE, 2);
  MyMatrix< float > data = _pCoordTransfer->get_transfer_data ();
  for (int r = 0; r < data.row_num (); ++r)
  {
    for (int c = 0; c < data.column_num (); ++c)
      output.bin_write< float > (&data[r][c]);
  }
  if (!output)
  {
    output.close ();
    return false;
  }

  output.close ();

  return true;
}



bool LightInputDriver::config (IN const MyMatrix< float >& cameraPoints,
  IN const MyMatrix< float >& projectPoints)
{
  return _pCoordTransfer->calibrate (cameraPoints, projectPoints);
}

bool LightInputDriver::get_point_in_camera (OUT Array< float >& point)
{
  return _pDetector->get_point_input (point);
}

bool LightInputDriver::get_point_in_project (OUT Array< float >& point)
{
  Array< float > origPoint;
  if (!_pDetector->get_point_input (origPoint))
    return false;
  _pCoordTransfer->camera_to_projector (origPoint, point);
  return true;
}